<template>
  <el-card>
    <div slot="header" class="clearfix">
      <span>用户任务节点属性</span>
    </div>
    <el-form ref="myform" size="mini">
      <el-tabs v-model="activeName" @tab-click="handleClick">

        <el-tab-pane key="first" label="常规" name="first">
          <el-form-item label="编号">
            <el-input v-model="id" />
          </el-form-item>
          <el-form-item label="名称">
            <el-input v-model="name" />
          </el-form-item>
          <WorkflowFormCom :init-workflow-form="formKey" @selectForm="selectForm" />
        </el-tab-pane>
        <el-tab-pane key="second" label="权限" name="second">
          <authority :init-object-from-parent="initObj" @changeAuthority="changeAuthority" />
        </el-tab-pane>
        <el-tab-pane key="third" label="监听" name="third">
          <el-container>
            <el-header>
              <el-button type="primary" @click="listenerVisible = true">执行监听器设置</el-button>
            </el-header>
            <el-main>
              <el-tag v-for="(tag,index) in table.listeners" :key="index" type="success">{{ tag.eventTypeLabel }} : {{ tag.listenerValueLabel }} : {{ tag.listenerValue }}</el-tag>
            </el-main>
          </el-container>
          <executionListener v-if="listenerVisible==true" :table="table" @saveListener="saveListener" @cancel="cancelListener" />
          <el-container>
            <el-header>
              <el-button type="primary" @click="userListenerVisible = true">任务监听器设置</el-button>
            </el-header>
            <el-main>
              <el-tag v-for="(tag,index) in userTaskTable.listeners" :key="index" type="success">{{ tag.eventTypeLabel }} : {{ tag.listenerValueLabel }} : {{ tag.listenerValue }}</el-tag>
            </el-main>
          </el-container>
          <userTaskListener v-if="userListenerVisible==true" :user-task-table="userTaskTable" @saveUserListener="saveUserListener" @cancelUserListener="cancelUserListener" />
        </el-tab-pane>
        <el-tab-pane key="fourth" label="会签" name="fourth">
          <el-form-item label="多实例方式" title="生成多实例方式">
            <el-radio v-model="dispatch" :label="true" @change="changeDispatch">collection</el-radio>
            <el-radio v-model="dispatch" :label="false" @change="changeDispatch">loop</el-radio>
          </el-form-item>
          <el-card v-if="!dispatch" shadow="never">
            <el-form-item label="审批人数" title="需等于候选用户数">
              <el-input v-model="loopCardinality" placeholder="请输入具体的数值或者变量" />
            </el-form-item>
          </el-card>
          <div v-if="dispatch || (!dispatch && loopCardinality!='')">
            <el-form-item label="通过方式">
              <el-radio v-model="radio" :label="true" @change="changeRadio">按比例</el-radio>
              <el-radio v-model="radio" :label="false" @change="changeRadio">按数量</el-radio>
            </el-form-item>

            <el-card v-if="radio" shadow="never">
              <el-form-item label="通过比例" title="通过数/总数">
                <el-row>
                  <el-col :span="14">
                    <el-input v-model="sign.weight" placeholder="0~1之间的数数或者变量" />
                  </el-col>
                  <el-col :span="10">
                    <el-select v-model="sign.logic" filterable placeholder="请选择">
                      <el-option v-for="(item) in logicOptions" :key="item.VALUE" :label="item.TEXT" :value="item.VALUE" />
                    </el-select>
                  </el-col>
                </el-row>
              </el-form-item>
              <el-form-item label="拒绝比例" title="不通过数/总数">
                <el-row>
                  <el-col :span="14">
                    <el-input v-model="sign.refuse" placeholder="0~1之间的数或者变量" />
                  </el-col>
                  <el-col :span="10">
                    <el-select v-model="sign.logic2" filterable placeholder="请选择">
                      <el-option v-for="(item) in logicOptions" :key="item.VALUE" :label="item.TEXT" :value="item.VALUE" />
                    </el-select>
                  </el-col>
                </el-row>
              </el-form-item>
              <el-form-item label="完成比例" title="完成数/总数">
                <el-input v-model="sign.complete" placeholder="0~1之间的数或者变量" />
              </el-form-item>
            </el-card>
            <el-card v-else>
              <el-form-item label="通过数" title="通过的人数（数值或者变量）">
                <el-row>
                  <el-col :span="14">
                    <el-input v-model="sign.weight" placeholder="数值或者变量" />
                  </el-col>
                  <el-col :span="10">
                    <el-select v-model="sign.logic" filterable placeholder="请选择">
                      <el-option v-for="(item) in logicOptions" :key="item.VALUE" :label="item.TEXT" :value="item.VALUE" />
                    </el-select>
                  </el-col>
                </el-row>
              </el-form-item>
              <el-form-item label="拒绝数" title="拒绝的人数（数值或者变量）">
                <el-row>
                  <el-col :span="14">
                    <el-input v-model="sign.refuse" placeholder="数值或者变量" />
                  </el-col>
                  <el-col :span="10">
                    <el-select v-model="sign.logic2" filterable placeholder="请选择">
                      <el-option v-for="(item) in logicOptions" :key="item.VALUE" :label="item.TEXT" :value="item.VALUE" />
                    </el-select>
                  </el-col>
                </el-row></el-form-item>
              <el-form-item label="完成数" title="总完成数（数值或者变量）">
                <el-input v-model="sign.complete" placeholder="数值或者变量" />
              </el-form-item>
            </el-card>
          </div>
        </el-tab-pane>

      </el-tabs>
    </el-form>
  </el-card>
</template>
<script>
const LogicOptions = [
  // { TEXT: '无', VALUE: '' },
  { TEXT: '并且', VALUE: '&&' },
  { TEXT: '或者', VALUE: '||' }
]
import authority from './authority.vue'
import executionListener from './executionListener.vue'
import userTaskListener from './userTaskListener.vue'
import elementHelper from '../js/helper/ElementHelper'
import WorkflowFormCom from './selectForm.vue'
import { ExecutionListenerTypes, UserTaskListenerTypes, ListenerTypes, DispatchVariable } from '../js/const/bpmnConsts.js'
export default {
  name: 'UserTaskProps',
  components: {
    authority,
    executionListener,
    userTaskListener,
    WorkflowFormCom
    // multiInstance,
    // authoritySign
  },
  props: {
    element: {
      required: false,
      type: Object,
      default: null
    }
  },
  inject: ['bpmnModeler'],
  data() {
    return {
      dispatch: false,
      activeName: 'first',
      modeling: null,
      id: this.element.id || '',
      name: '',
      formKey: '',
      candidateUsers: [],
      candidateGroups: [],
      assignee: [],
      initObj: {
        candidateStarterGroups: [],
        candidateStarterUsers: [],
        initiator: []
      },
      table: {
        listeners: [],
        selectedRow: null
      },
      userTaskTable: {
        listeners: [],
        selectedRow: null
      },
      listenerVisible: false,
      userListenerVisible: false,
      /** 会签节点属性配置 */
      sign: {
        weight: '',
        logic: '||',
        refuse: '',
        logic2: '||',
        complete: ''
      },
      loopCardinality: '',
      logicOptions: LogicOptions,
      radio: true
    }
  },
  watch: {
    name: {
      handler(newVal, oldVal) {
        this.modeling.updateProperties(this.element, {
          name: newVal
        })
      }
    },

    // 监视元素变化
    element: {
      deep: true,
      immediate: true,
      handler(newVal, oldVal) {
        if (newVal.type === 'bpmn:UserTask') {
          const that = this
          const businessObject = newVal.businessObject
          this.name = businessObject.name
          this.formKey = businessObject.get('formKey')

          //
          const candidateGroupsTemp = businessObject.get('candidateGroups')
          // 解决后端反显和切换节点反显candidateGroupsTemp类型不一致问题
          if (candidateGroupsTemp && candidateGroupsTemp.length > 0) {
            if (Array.isArray(candidateGroupsTemp)) {
              // 切换节点反显
              this.candidateGroups = businessObject.get('candidateGroups')
            } else {
              // 后端反显
              this.candidateGroups = businessObject.get('candidateGroups').split(',')
            }
            this.initObj['candidateStarterGroups'] = this.candidateGroups
          }
          //
          const candidateassigneeTemp = businessObject.get('assignee')
          // 解决后端反显和切换节点反显candidateGroupsTemp类型不一致问题
          if (candidateassigneeTemp && candidateassigneeTemp.length > 0) {
            if (Array.isArray(candidateassigneeTemp)) {
              // 切换节点反显
              this.assignee = businessObject.get('assignee')
            } else {
              // 后端反显
              this.assignee = businessObject.get('assignee').split(',')
            }
            this.initObj['initiator'] = this.assignee
          }
          //
          const candidateUsersTemp = businessObject.get('candidateUsers')
          // 解决后端反显和切换节点反显candidateGroupsTemp类型不一致问题
          if (candidateUsersTemp && candidateUsersTemp.length > 0) {
            if (Array.isArray(candidateUsersTemp)) {
              // 切换节点反显
              this.candidateUsers = businessObject.get('candidateUsers')
            } else {
              // 后端反显
              this.candidateUsers = businessObject.get('candidateUsers').split(',')
            }
            this.initObj['candidateStarterUsers'] = this.candidateUsers
          }
          const extensionElements = businessObject.get('extensionElements')
          if (extensionElements) {
            if (extensionElements.get('values')) {
              extensionElements.get('values').forEach(t => {
                if (t.$type === 'activiti:TaskListener') {
                  that.userTaskTable.listeners.push(that.getObj(t, UserTaskListenerTypes, ListenerTypes))
                } else if (t.$type === 'activiti:ExecutionListener') {
                  that.table.listeners.push(that.getObj(t, ExecutionListenerTypes, ListenerTypes))
                }
              })
            }
          }
          const multiInstance = this.element.businessObject.get('loopCharacteristics')
          if (multiInstance) {
            // this.sign.isSequential = false
            // this.sign.elementVariable = multiInstance.get('elementVariable')
            const elementVariable = multiInstance.get('elementVariable')
            const collection = multiInstance.get('collection')
            if (elementVariable && collection) {
              this.dispatch = true
            } else {
              this.dispatch = false
            }
            const completionCondition = multiInstance.get('completionCondition')
            if (completionCondition) {
              // "${pass/total>=0.1||refuse/total>=0.1}"
              const str = completionCondition.body
              if (str.indexOf('/') !== -1) {
                this.radio = true
              } else {
                this.radio = false
              }

              // "pass/total>=0.1||refuse/total>=0.1||complete"
              const tempstr = str.replace(/\$/g, '').replace(/\{/g, '').replace(/\}/g, '').replace(/\&/g, '')
              const array = tempstr.split('||')
              for (const item of array) {
                const tempWeight = item.substring(item.indexOf('=') + 1, item.length)
                if (item.indexOf('pass') !== -1 || item.indexOf('pass/total') !== -1) {
                  this.sign.weight = tempWeight
                } else if (item.indexOf('refuse') !== -1 || item.indexOf('refuse/total') !== -1) {
                  this.sign.refuse = tempWeight
                } else {
                  this.sign.complete = tempWeight
                }
              }
              // 设置逻辑符

              const reg = /[\|\&]/ig
              const regRes = str.match(reg)
              if (regRes) {
                if (regRes.length === 4) {
                  this.logic = regRes[0] + regRes[1]
                  this.logic2 = regRes[2] + regRes[3]
                } else if (regRes.length === 2) {
                  if (str.indexOf('pass') !== -1) {
                    this.sign.logic = regRes[0] + regRes[1]
                  } else {
                    this.sign.logic2 = regRes[0] + regRes[1]
                  }
                }
              }

              // if (str.indexOf('||') !== -1 || str.indexOf('&&') !== -1) {
              //   this.sign.logic = str.indexOf('||') !== -1 ? '||' : '&&'
              //   const strArray = str.split(this.sign.logic)
              //   const indexWeight = strArray[0].indexOf('=')
              //   this.sign.weight = strArray[0].substring(indexWeight + 1, strArray[0].length)
              //   const indexRefuse = strArray[1].indexOf('=')
              //   this.sign.refuse = strArray[1].substring(indexRefuse + 1, strArray[1].length - 1)
              // } else {
              //   const indexWeight = completionCondition.body.indexOf('=')
              //   const tempWeight = completionCondition.body.substring(indexWeight + 1, completionCondition.body.length - 1)
              //   if (str.indexOf('pass') !== -1 || str.indexOf('pass/total') !== -1) {
              //     this.sign.weight = tempWeight
              //   } else if (str.indexOf('refuse') !== -1 || str.indexOf('refuse/total') !== -1) {
              //     this.sign.refuse = tempWeight
              //   }
              // }
            }

            const loopCardinality = multiInstance.get('loopCardinality')
            if (loopCardinality) {
              const loopBody = loopCardinality.body
              if (loopBody.indexOf('{') !== -1) {
                this.loopCardinality = loopBody.substring(loopBody.indexOf('{') + 1, loopBody.indexOf('}'))
              } else {
                this.loopCardinality = loopCardinality.body
              }
            }
          }
        }
      }
    },
    formKey: {
      handler(newVal, oldVal) {
        this.modeling.updateProperties(this.element, { 'formKey': newVal })
      }
    },
    candidateGroups: {
      handler(newVal, oldVal) {
        this.modeling.updateProperties(this.element, { 'candidateGroups': newVal })
      }
    },
    candidateUsers: {
      handler(newVal, oldVal) {
        this.modeling.updateProperties(this.element, { 'candidateUsers': newVal })
      }
    },
    assignee: {
      handler(newVal, oldVal) {
        this.modeling.updateProperties(this.element, { 'assignee': newVal })
      }
    },
    /** 执行监听器 */
    'table.listeners': {
      immediate: true,
      deep: true,
      handler(newVal, oldVal) {
        if (newVal) {
          const bpmnModeler = this.bpmnModeler()
          const bpmnFactory = bpmnModeler.get('bpmnFactory')
          let extensionElements = this.element.businessObject.get('extensionElements')
          if (!extensionElements) {
            extensionElements = elementHelper.createElement('bpmn:ExtensionElements', null, this.element, bpmnFactory)
          }
          extensionElements.values = extensionElements.get('values').filter(t => { return t.$type !== 'activiti:ExecutionListener' })
          newVal.forEach(evt => {
            const executionListener = elementHelper.createElement('activiti:ExecutionListener', null, this.element, bpmnFactory)
            // executionListener.$attrs['event'] = evt.eventType
            // executionListener.$attrs[evt.listenerType] = evt.listenerValue
            executionListener['event'] = evt.eventType
            executionListener[evt.listenerType] = evt.listenerValue
            extensionElements.get('values').push(executionListener)
          })
          const modeling = bpmnModeler.get('modeling')
          modeling.updateProperties(this.element, {
            extensionElements: extensionElements
          })
        }
      }
    },
    /** 任务监听器 */
    'userTaskTable.listeners': {
      immediate: true,
      deep: true,
      handler(newVal, oldVal) {
        if (newVal) {
          const bpmnModeler = this.bpmnModeler()
          const bpmnFactory = bpmnModeler.get('bpmnFactory')
          let extensionElements = this.element.businessObject.get('extensionElements')
          if (!extensionElements) {
            extensionElements = elementHelper.createElement('bpmn:ExtensionElements', null, this.element, bpmnFactory)
          }
          extensionElements.values = extensionElements.get('values').filter(t => { return t.$type !== 'activiti:TaskListener' })
          newVal.forEach(evt => {
            const executionListener = elementHelper.createElement('activiti:TaskListener', null, this.element, bpmnFactory)
            // executionListener.$attrs['event'] = evt.eventType
            // executionListener.$attrs[evt.listenerType] = evt.listenerValue
            executionListener['event'] = evt.eventType
            executionListener[evt.listenerType] = evt.listenerValue
            extensionElements.get('values').push(executionListener)
          })
          const modeling = bpmnModeler.get('modeling')
          modeling.updateProperties(this.element, {
            extensionElements: extensionElements
          })
        }
      }
    },
    /** 会签节点属性 */
    loopCardinality: {
      immediate: true,
      handler(newVal, oldVal) {
        if (newVal) {
          if (this.loopCardinality) {
            const bpmnModeler = this.bpmnModeler()
            const bpmnFactory = bpmnModeler.get('bpmnFactory')
            const multiInstance = this.element.businessObject.get('loopCharacteristics')
            /** loop */
            if (multiInstance) {
              let loopCardinality = multiInstance.get('loopCardinality')
              if (!loopCardinality) {
                loopCardinality = elementHelper.createElement('bpmn:Expression', null, multiInstance, bpmnFactory)
              }

              if (Number.isNaN(Number(this.loopCardinality))) {
                const loop = '${' + this.loopCardinality + '}'
                loopCardinality['body'] = loop
              } else {
                loopCardinality['body'] = this.loopCardinality
              }

              multiInstance['loopCardinality'] = loopCardinality

              // let completionCondition = multiInstance.get('completionCondition')
              // if (this.sign.weight || this.sign.refuse) {
              //   if (!completionCondition) {
              //     completionCondition = elementHelper.createElement('bpmn:Expression', null, multiInstance, bpmnFactory)
              //   }
              //   const passExpression = this.radio ? 'pass/total' : 'pass'
              //   const refuseExpression = this.radio ? 'refuse/total' : 'refuse'
              //   if (this.sign.weight && this.sign.refuse) {
              //     completionCondition['body'] = '${' + `${passExpression}>=${this.sign.weight}` + this.sign.logic + `${refuseExpression}>=${this.sign.refuse}` + '}'
              //   } else if (this.sign.weight) {
              //     completionCondition['body'] = '${' + `${passExpression}=${this.sign.weight}` + '}'
              //   } else if (this.sign.refuse) {
              //     completionCondition['body'] = '${' + `${refuseExpression}>=${this.sign.refuse}` + '}'
              //   }

              //   multiInstance['completionCondition'] = completionCondition
              // } else {
              //   if (completionCondition) {
              //     delete multiInstance.completionCondition
              //   }
              // }

              const modeling = bpmnModeler.get('modeling')
              modeling.updateProperties(this.element, {
                loopCharacteristics: multiInstance
              })
            }
          }
        }
      }
    },
    sign: {
      immediate: true,
      deep: true,
      handler(newVal, oldVal) {
        if (newVal) {
          const bpmnModeler = this.bpmnModeler()
          const bpmnFactory = bpmnModeler.get('bpmnFactory')
          const multiInstance = this.element.businessObject.get('loopCharacteristics')
          /** completionCondition*/
          if (multiInstance) {
            let completionCondition = multiInstance.get('completionCondition')
            if (this.sign.weight || this.sign.refuse || this.sign.complete) {
              if (!completionCondition) {
                completionCondition = elementHelper.createElement('bpmn:Expression', null, multiInstance, bpmnFactory)
              }
              const passExpression = this.radio ? 'pass/total' : 'pass'
              const refuseExpression = this.radio ? 'refuse/total' : 'refuse'
              const completeExpression = this.radio ? 'nrOfCompletedInstances/nrOfInstances' : 'nrOfCompletedInstances'
              let passExp = ''
              let refuseExp = ''
              let completeExp = ''
              if (this.sign.weight) {
                passExp = `${passExpression}>=${this.sign.weight}`
              }
              if (this.sign.refuse) {
                refuseExp = `${refuseExpression}>=${this.sign.refuse}`
              }
              if (this.sign.complete) {
                completeExp = `${completeExpression}>=${this.sign.complete}`
              }
              if (passExp && refuseExp && completeExp) {
                completionCondition['body'] = '${' + `${passExp}${this.sign.logic}${refuseExp}${this.sign.logic2}${completeExp}` + '}'
              } else if (passExp && refuseExp) {
                completionCondition['body'] = '${' + `${passExp}${this.sign.logic}${refuseExp}` + '}'
              } else if (passExp && completeExp) {
                completionCondition['body'] = '${' + `${passExp}${this.sign.logic}${completeExp}` + '}'
              } else if (passExp) {
                completionCondition['body'] = '${' + `${passExp}` + '}'
              } else if (refuseExp && completeExp) {
                completionCondition['body'] = '${' + `${refuseExp}${this.sign.logic2}${completeExp}` + '}'
              } else if (refuseExp) {
                completionCondition['body'] = '${' + `${refuseExp}` + '}'
              } else if (completeExp) {
                completionCondition['body'] = '${' + `${completeExp}` + '}'
              }
              // if (this.sign.weight && this.sign.refuse) {
              //   completionCondition['body'] = '${' + `${passExpression}>=${this.sign.weight}` + this.sign.logic + `${refuseExpression}>=${this.sign.refuse}` + '}'
              // } else if (this.sign.weight) {
              //   completionCondition['body'] = '${' + `${passExpression}=${this.sign.weight}` + '}'
              // } else if (this.sign.refuse) {
              //   completionCondition['body'] = '${' + `${refuseExpression}>=${this.sign.refuse}` + '}'
              // }

              multiInstance['completionCondition'] = completionCondition
            } else {
              if (completionCondition) {
                delete multiInstance.completionCondition
              }
            }

            const modeling = bpmnModeler.get('modeling')
            modeling.updateProperties(this.element, {
              loopCharacteristics: multiInstance
            })
          }
        }
      }
    }
  },
  mounted() {
    const bpmnModeler = this.bpmnModeler()
    this.modeling = bpmnModeler.get('modeling')
  },
  methods: {
    handleClick(tab, event) {
      console.log(tab, event)
    },
    changeAuthority(data) {
      this.candidateUsers = data.users
      this.candidateGroups = data.groups
      this.assignee = data.initiator
      this.initObj = {
        candidateStarterGroups: data.groups,
        initiator: data.initiator,
        candidateStarterUsers: data.users
      }
    },
    saveListener(data) {
      this.table.listeners = data
      this.listenerVisible = false
    },
    cancelListener() {
      this.listenerVisible = false
    },
    saveUserListener(data) {
      this.userTaskTable.listeners = data
      this.userListenerVisible = false
    },
    cancelUserListener() {
      this.userListenerVisible = false
    },
    getObj(t, types, expressions) {
      const obj = {
        // eventType: t.$attrs.event,
        eventType: t.event,
        eventTypeLabel: '',
        listenerType: '',
        listenerValueLabel: '',
        listenerValue: ''
      }
      // const ind = findIndex(types, { eventType: t.$attrs.event })
      const ind = types.findIndex(item => { return item.eventType === t.event })
      if (ind !== -1) {
        obj.eventTypeLabel = types[ind].eventTypeLabel
      }

      // for (const item in t.$attrs) {
      for (const item in t) {
        const index = expressions.findIndex(it => { return it.listenerType === item })
        if (index !== -1) {
          obj.listenerType = item
          obj.listenerValueLabel = expressions[index].listenerValueLabel
          // obj.listenerValue = t.$attrs[item]
          obj.listenerValue = t[item]
        }
      }
      return obj
    },
    selectForm(data) {
      this.formKey = data
    },
    /** 选择分发节点 */
    changeDispatch() {
      this.sign.weight = ''
      this.sign.refuse = ''
      this.loopCardinality = ''
      this.sign.complete = ''
      const bpmnModeler = this.bpmnModeler()
      const multiInstance = this.element.businessObject.get('loopCharacteristics')
      const modeling = bpmnModeler.get('modeling')
      if (this.dispatch) {
        if (multiInstance) {
          /** 清除loopCardinality  */
          const loopCardinality = multiInstance.get('loopCardinality')
          if (loopCardinality) {
            delete multiInstance.loopCardinality
            // const completionCondition = multiInstance.get('completionCondition')
            // if (completionCondition) {
            //   delete multiInstance.completionCondition
            // }
          }
          multiInstance['collection'] = DispatchVariable.collection
          multiInstance['elementVariable'] = DispatchVariable.elementVariable

          modeling.updateProperties(this.element, {
            loopCharacteristics: multiInstance
          })
        }
      } else {
        if (multiInstance) {
          delete multiInstance.collection
          delete multiInstance.elementVariable
          // multiInstance['collection'] =null
          // multiInstance['elementVariable'] = DispatchVariable.elementVariable
          modeling.updateProperties(this.element, {
            loopCharacteristics: multiInstance
          })
        }
      }
    },
    changeRadio() {
      this.sign.weight = ''
      this.sign.logic = '||'
      this.sign.refuse = ''
      this.sign.complete = ''
    }
  }

}
</script>
<style>

</style>
